
#include <BFont>
#include "member_BTreeItem.h"
#include "member_BTreeWidget.h"

using namespace BWE;

member_BTreeWidget::member_BTreeWidget(BTreeWidget* treeWidget)
{
	boss = treeWidget;
	indent = 16;
	space = 2;
	rowHeight = 0;
	headerHeight = 23;
	imageSize.set(16, 16);
	hoveredItem = 0;
	multiChoose = false;
	continuChoose = false;
	hoveredIndicator = false;
}
member_BTreeWidget::~member_BTreeWidget()
{

}

bool member_BTreeWidget::freshRects()
{
	const BFont* font = boss->font();
	if (!font)
		return false;

	rowHeight = bMax(rowHeight, font->height());
	boss->verticalScrollBar()->setStep(rowHeight);
	boss->horizontalScrollBar()->setStep(rowHeight);

	if (arrowSize < 2 || arrowSize > rowHeight)
		arrowSize = rowHeight;

	const BRect& crect = boss->clientRect();
	BRect area = boss->area();
	int x = area.x();
	int y = area.y();

	int height = 0;
	int width = area.width();
	int maxWidth = 0;

	visualItems.reset();
	for (int i = 0; i < topItems.size(); i++)
	{
		BTreeItem* item = topItems[i];
		freshItemRect(font, item, x, y, height, width, maxWidth);
	}
	area.setHeight(height);
	area.setWidth(maxWidth);
	if (boss->horizontalScrollBarPolicy() == ScrollBarPolicy_Never)
		area.setWidth(crect.width());
	boss->setArea(area);

	if(arrowSize > 3)
	{
		int w = arrowSize;
		int h = arrowSize;

		shrinkA.set(w / 4, h / 4);
		shrinkB.set(w / 4, h / 4 * 3);
		shrinkC.set(w / 4 * 3, h / 2);

		expandA.set(w / 4, h / 4);
		expandB.set(w / 2, h / 4 * 3);
		expandC.set(w / 4 * 3, h / 4);
	}

	return true;
}
void member_BTreeWidget::freshItemRect(const BFont* font, BTreeItem* item, int x, int& y, int& height, int width, int& realWidth)
{
	const BRect& crect = boss->clientRect();

	if (item_member(item)->dirty)
	{
		member_BTreeItem* im = item_member(item);
		im->indent = item->level() * indent;
		if (im->widget)
		{
			im->sizeHint = im->widget->sizeHint() + BSize(im->indent, 0);
		}
		else
		{
			im->textSize = font->textSize(item_member(item)->text);
			im->sizeHint = im->textSize + BSize(im->indent + rowHeight + rowHeight, 0);
		}
	}

	BSize sizeHint = item_member(item)->sizeHint;
	if (realWidth < sizeHint.width())
		realWidth = sizeHint.width();

	int itemWidth = bMax(width, crect.width());
	int itemHeight = bMax(sizeHint.height(), rowHeight);
	BRect& rect = item_member(item)->rect;
	rect.set(x, y, itemWidth, itemHeight);
	item_member(item)->adjust();

	if (rect.bottom() > crect.top() && rect.top() < crect.bottom())
		visualItems.append(item);

	y += itemHeight + space;
	height += itemHeight + space;

	if(item_member(item)->expanded)
	{
		for(int i = 0; i < item->childCount(); i++)
		{
			BTreeItem* child = item->child(i);
			freshItemRect(font, child, x, y, height, width, realWidth);
		}
	}
}

void member_BTreeWidget::expandAll(BTreeItem* item)
{
	if(item)
	{
		item->expand();
		for(int i = 0; i < item->childCount(); i++)
		{
			BTreeItem* child = item->child(i);
			expandAll(child);
		}
	}
}
void member_BTreeWidget::shrinkAll(BTreeItem* item)
{
	if(item)
	{
		item->shrink();
		for(int i = 0; i < item->childCount(); i++)
		{
			BTreeItem* child = item->child(i);
			shrinkAll(child);
		}
	}
}

void member_BTreeWidget::slotCountChanged(BObject* object, const BValue& value)
{
	dirty = true;
	boss->fresh();
}
